﻿using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;
using static zy_simu.Data.DevPreDef;

namespace zy_simu.Data
{
    public class DisplayPanel : ComponentBase
    {
        protected string title = "";
        protected byte mkey = 0;                // 鼠标button产生的模拟key
        protected byte kkey = 0;                // 键盘产生的模拟key
        protected string KeyStateString = " ";  // 实时key状态表述

        [Inject]
        protected DeviceSnap dev_snap { get; set; }

        public void Init()
        {
            if (dev_snap.dev_type == 2432601)
                title = $"DisplayPanel - whh{dev_snap.dev_type}";
            else if (dev_snap.dev_type == 2432602)
                title = $"DisplayPanel - MD{dev_snap.dev_type}";
            else if (dev_snap.dev_type == 2432603)
                title = $"DisplayPanel - GD6_{dev_snap.dev_type}";
            else
                title = $"DisplayPanel - AKM{dev_snap.dev_type}";
            kkey = mkey = 0;
        }
        // key related functions --------------------------------------------------------------------------------------------------
        public byte GetKey()
        {
            return (byte)(kkey | mkey);
        }
        public void Display()
        {

            if(digital_value.Length != dev_snap.digital_num)
                digital_value = new char[dev_snap.digital_num];

            // display key states
            KeyStateString = "按键状态:";
            for (int i = 0; i < dev_snap.entity_key_num; i++)
            {
                string str;
                if ((dev_snap.key_state[i] & 0x80000000) == 0)
                    str = string.Format("{0}: up", dev_snap.key_tb[i]);
                else if ((dev_snap.key_state[i] & 0x7fffffff) > 1000)
                    str = string.Format("{0}: keep-{1}", dev_snap.key_tb[i], (dev_snap.key_state[i] & 0x7fffffff));
                else
                    str = string.Format("{0}: down", dev_snap.key_tb[i]);
                KeyStateString += string.Format(" {0} |", str);
            }
            ParsingDispMemory(dev_snap.disp_memory);
            //macro_service.record_key(key_state);
            InvokeAsync(StateHasChanged);
        }
        public void CloseDisplay()
        {
            for (int i = 0; i < icon_state.Length; i++)
                icon_state[i] = 0;
            for (int i = 0; i < digital_value.Length; i++)
                digital_value[i] = ' ';
        }


        // 鼠标button产生的模拟key
        protected void OnMouseDown(int i)
        {
            if (i >= 0 && i < dev_snap.entity_key_num)
                mkey |= (byte)(1 << i);
        }
        protected void OnMouseUp(int i)
        {
            if (i >= 0 && i < dev_snap.entity_key_num)
                mkey &= (byte)~(1 << i);
        }
        // 键盘产生的模拟key, 含快捷键
        protected void HandleKeyUpDown(KeyboardEventArgs e)
        {
            byte idx = dev_snap.entity_key_num;
            switch (e.Key)
            {
                case "s":
                    idx = (byte)DispKeyIdx.SET;
                    break;
                case "f":
                    idx = (byte)DispKeyIdx.FUNC;
                    break;
                case "t":
                    idx = (byte)DispKeyIdx.TOGGLE;
                    break;
                case "=":
                    idx = (byte)DispKeyIdx.PLUS;
                    break;
                case "+":
                    idx = (byte)DispKeyIdx.PLUS;
                    break;
                case "-":
                    idx = (byte)DispKeyIdx.MINUS;
                    break;
            }
            if (idx >= dev_snap.entity_key_num) // 都不是
                return;
            if (e.Type == "keydown")
                kkey |= (byte)(1 << dev_snap.key_tb[idx]);
            else if (e.Type == "keyup")
                kkey &= (byte)~(1 << dev_snap.key_tb[idx]);
        }

        protected string GetButtonBKColor(int i)
        {
            if (dev_snap.dev_type == 0) return "background-color:lightgray"; // 没有同步device, 默认全显示
            if (i < dev_snap.entity_key_num)
                return "background-color:lightgray";
            else
                return "background-color:#282828";
        }
        protected string GetButtonIcon(int i)
        {
            if (i < dev_snap.entity_key_num && dev_snap.key_tb[i] != (byte)KEY_INVALID)
            {
                return KeyDescriptionTable[dev_snap.key_tb[i]].Item2;
            }
            else
            {
                i %= 10; // 没有指定图标，返回简单0-9数字图标
                return $"fas fa-{i}";
            }
        }
        protected string GetIconClass(int i)
        {
            return IconDescriptionTable[i].Item3;
        }
        protected string GetIconColor(int i, string color)
        {
            if(dev_snap.dev_type == 0) return "color:dimgrey"; // 没有同步device, 默认显示所有icon
            if (dev_snap.disp_item_codec_tb[i].grid == DISP_ITEM_INVALID) return "color:#282828"; // 无效图标
            if (icon_state[i] == 0)
                return "color:dimgrey";
            else 
                return $"color:{color}";
        }
        protected string GetDigitalBKColor(int i)
        {
            if (i < digital_value.Length)
                return "color: dimgrey";
            else
                return "color: #282828";
        }

        public byte[] icon_state { get; set; } = new byte[(byte)DispItemIdx.ICON_NUM];  // every icon, 1=亮
        public char[] digital_value { get; set; } = new char[(byte)DispItemIdx.DIGITAL_NUM];  // 从左到右 led数码管value, 0表示不显示
        // LedCharCode ------------------------------------------------------------------------
        protected Dictionary<byte, char> led_char_codes = new Dictionary<byte, char> {
                                 // MASK -------------- | HG FE DCBA |
            {(byte)0x3f, '0'},   // '0' --  ABCDEF   -- |    11 1111 | --
            {(byte)0x06, '1'},   // '1' --   BC      -- |        11  | --
            {(byte)0x5b, '2'},   // '2' --  AB DE G  -- |  1  1 1 11 | --
            {(byte)0x4f, '3'},   // '3' --  ABCD  G  -- |  1    1111 | --
            {(byte)0x66, '4'},   // '4' --   BC  FG  -- |  1 1   11  | --
            {(byte)0x6d, '5'},   // '5' --  A CD FG  -- |  1 1  11 1 | --
            {(byte)0x7d, '6'},   // '6' --  A CDEFG  -- |  1 11 11 1 | --
            {(byte)0x07, '7'},   // '7' --  ABC      -- |        111 | --
            {(byte)0x7f, '8'},   // '8' --  ABCDEFG  -- |  1 11 1111 | --
            {(byte)0x6f, '9'},   // '9' --  ABCD FG  -- |  1 1  1111 | --
            {(byte)0x77, 'A'},   // 'A' --  ABC EFG  -- |  1 11  111 | --
            {(byte)0x7c, 'b'},   // 'b' --    CDEFG  -- |  1 11 11   | --
            {(byte)0x39, 'C'},   // 'C' --  A  DEF   -- |    11 1  1 | --
            {(byte)0x58, 'c'},   // 'c' --     DE G  -- |  1  1 1    | --
            {(byte)0x5e, 'd'},   // 'd' --   BCDE G  -- |  1  1 111  | --
            {(byte)0x79, 'E'},   // 'E' --  A  DEFG  -- |  1 11 1  1 | --
            {(byte)0x71, 'F'},   // 'F' --  A   EFG  -- |  1 11    1 | --
            {(byte)0x76, 'H'},   // 'H' --   BC EFG  -- |  1 11  11  | --
            {(byte)0x30, 'i'},   // '1' --      EF   -- |    11      | --
            {(byte)0x38, 'L'},   // 'L' --     DEF   -- |    11 1    | --
            {(byte)0x54, 'n'},   // 'n' --    C E G  -- |  1  1  1   | --
            {(byte)0x5c, 'o'},   // 'o' --    CDE G  -- |  1  1 11   | --
            {(byte)0x73, 'P'},   // 'P' --  AB  EFG  -- |  1 11   11 | --
            {(byte)0x50, 'r'},   // 'r' --      E G  -- |  1  1      | --
            {(byte)0x78, 't'},   // 't' --     DEFG  -- |  1 11 1    | --
            {(byte)0x40, '-'},   // '-' --        G  -- |  1         | --
            {(byte)0x00, ' '},   // ' ' --        G  -- |            | --
            {(byte)0x52, '/'},   // '/' --   B  E G  -- |  1  1   1  | --
            {(byte)0xff, 'Z'},   // 'Z' --  ABCDEFGH -- | 11 11 1111 | --
            {(byte)0x3e, 'U'},   // '0' --   BCDEF   -- |    11 111  | --
            {(byte)0x02, '\''},  // ''' --   B       -- |        1   | --
            {(byte)0x04, ','},   // ',' --    C      -- |       1    | --
        };

        // translate disp memory to icon state and digital value
        private void ParsingDispMemory(byte[] disp_memory)
        {
            for (byte grid = 0; grid < disp_memory.Length; grid++)
            {
                for (byte i = (byte)DispItemIdx.D1; i < (byte)DispItemIdx.ALL_NUM; i++) // digital
                {
                    if (dev_snap.disp_item_codec_tb[i].grid < DISP_ITEM_INVALID && dev_snap.disp_item_codec_tb[i].grid == grid)
                    {
                        digital_value[i - (byte)DispItemIdx.ICON_NUM] = led_char_codes[(byte)(disp_memory[grid] & 0x7f)];
                        break;
                    }
                }

                for (byte seg = 0; seg < 8; seg++) // icon
                {
                    for (byte i = 0; i < (byte)DispItemIdx.ICON_NUM; i++)
                    {
                        if (dev_snap.disp_item_codec_tb[i].grid == grid && dev_snap.disp_item_codec_tb[i].seg == seg)
                        {
                            icon_state[i] = (byte)(((disp_memory[grid] & (1 << seg)) != 0) ? 1 : 0);
                            break;
                        }
                    }

                }
            }

        }

    }
}
